package com.hjk.common.utils.check;

import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 校验工具类,判断非空,空串等等
 *
 * @author 黄军凯
 * @date 2019/5/2
 */
@Slf4j
public class Check {

    /**
     * 批量校验 根据key从数据库查询的数据是否存在
     * @param objectMap
     * @param key
     * @param <T>
     * @return
     */
    private <T> T getObjectElseThrow(Map<String, T> objectMap, String key, String errorMsg) {
        T obj = null;
        try {
            obj = objectMap.get(key);
        } catch (Exception e) {
            throwErrorMsg(e, errorMsg);
        }
        if (Check.isEmpty(obj)) {
            throw new RuntimeException(errorMsg);
        }
        return obj;
    }
    /**
     * 记录错误日志,并抛出异常
     *
     * @param e        Exception
     * @param errorMsg 错误信息
     */
    private void throwErrorMsg(Exception e, String errorMsg) {
        log.error(errorMsg, e);
        throw new RuntimeException(errorMsg + e.getMessage());
    }


    /**
     * 为空则返回null,不为空返回自身
     * @param t 值
     * @param <T> 泛型
     * @return null 或者自身
     */
    public static <T> T ofNullable(T t) {
        return isEmpty(t) ? null : (T) t.toString();
    }

    /**
     * 判断对象是否Empty(null或元素为0)
     * 实用于对如下对象做判断:String Collection及其子类 Map及其子类,数组等等
     *
     * @param obj 待检查对象
     * @return boolean 返回的布尔值
     */
    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj == "") {
            return true;
        }
        if (obj instanceof String) {
            return strIsBlank((String) obj);
        } else if (obj instanceof Collection) {
            return collectionIsEmpty((Collection) obj);
        } else if (obj.getClass().isArray()) {
            return arrIsEmpty((Object[]) obj);
        } else if (obj instanceof Map) {
            return ((Map) obj).size() == 0;
        }
        return false;
    }

    /**
     * 判断对象是否为NotEmpty(!null或元素大于0)
     * 实用于对如下对象做判断:String Collection及其子类 Map及其子类
     *
     * @param obj 待检查对象
     * @return boolean 返回的布尔值
     */
    public static boolean isNotEmpty(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == "") {
            return false;
        }
        if (obj instanceof String) {
            return strIsNotBlank((String) obj);
        } else if (obj instanceof Collection) {
            return collectionIsNotEmpty((Collection) obj);
        } else if (obj.getClass().isArray()) {
            return arrIsNonEmpty((Object[]) obj);
        } else if (obj instanceof Map) {
            return ((Map) obj).size() != 0;
        }
        return true;
    }

    public static void main(String[] args) {
        Set<String> arr = new HashSet<>();
        System.out.println(Check.isEmpty(arr));
        System.out.println(Check.isNotEmpty(arr));
    }

    /**
     * 校验 数字类型 结果大于 0
     *
     * @param number
     * @return
     */
    public static boolean isSuccess(Number number) {
        if (number == null) {
            return false;
        }
        if (number instanceof Byte) {
            return number.byteValue() > 0;
        } else if (number instanceof Short) {
            return number.byteValue() > 0;
        } else if (number instanceof Integer) {
            return number.byteValue() > 0;
        } else if (number instanceof Long) {
            return number.byteValue() > 0;
        } else if (number instanceof Float) {
            return number.byteValue() > 0;
        } else if (number instanceof Double) {
            return number.byteValue() > 0;
        }
        return false;
    }

    /**
     * 校验 数字类型 结果小于 0
     */
    public static boolean isNotSuccess(Number number) {
        return !isSuccess(number);
    }


    /**
     * 数组是否为空
     *
     * @param <T>   数组元素类型
     * @param array 数组
     * @return 是否为空
     */
    public static <T> boolean arrIsEmpty(T[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 数组是否不为空
     *
     * @param <T>   数组元素类型
     * @param array 数组
     * @return 是否为空
     */
    public static <T> boolean arrIsNonEmpty(T[] array) {
        return !arrIsEmpty(array);
    }

    /**
     * 判断对象不为空
     */
    public static boolean objectNonNull(Object obj) {
        return Objects.nonNull(obj);
    }

    /**
     * 判断对象为空
     */
    public static boolean objectIsNull(Object obj) {
        return Objects.isNull(obj);
    }

    /**
     * 断言对象为空
     */
    public static void checkObjectIsNull(Object obj) {
        if (Objects.isNull(obj)) {
            return;
        }
        throw new NullPointerException("对象{" + obj.getClass() + "}不为空");
    }


    /**
     * 判断集合不为空
     */
    public static boolean collectionIsNotEmpty(Collection<?> list) {
        return !list.isEmpty();
    }

    /**
     * 判断集合为空
     */
    public static boolean collectionIsEmpty(Collection<?> list) {
        return list.isEmpty();
    }

    /**
     * 判断字符串不为空字符串,空格也为空串 "   " == false
     */
    public static boolean strIsNotBlank(final CharSequence cs) {
        return !strIsBlank(cs);
    }

    /**
     * 是否空白符<br>
     * 空白符包括空格、制表符、全角空格和不间断空格<br>
     *
     * @param c 字符
     * @return 是否空白符
     * @see Character#isWhitespace(int)
     * @see Character#isSpaceChar(int)
     * @since 4.0.10
     */
    public static boolean isBlankChar(int c) {
        return Character.isWhitespace(c) || Character.isSpaceChar(c) || c == '\ufeff' || c == '\u202a';
    }


    /**
     * 判断字符串为空白
     */
    public static boolean strIsBlank(final CharSequence cs) {
        int strLen;
        //匹配 """""""  +
        if (Pattern.matches("\"*|'*|_*|,*|\\.*|;*",cs )) {
            return true;
        }

        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (!isBlankChar(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }



    /**
     * 判断字符串不为空
     */
    public static boolean strIsNotEmpty(final CharSequence cs) {
        return !strIsEmpty(cs);
    }

    /**
     * 判断字符串为空
     */
    public static boolean strIsEmpty(final CharSequence cs) {
        return cs == null || cs.length() == 0;
    }

    /**
     * 断言
     */
    public static void checkArgument(boolean expression) {
        if (!expression) {
            throw new IllegalArgumentException();
        }
    }

    /**
     * 断言
     *
     * @param errorMessage 异常信息
     */
    public static void checkArgument(boolean expression, Object errorMessage) {
        if (!expression) {
            throw new IllegalArgumentException(String.valueOf(errorMessage));
        }
    }


    /**
     * 断言集合不为空
     *
     * @param errorMessage 异常信息
     */
    public static void checkCollectionIsNotEmpty(Collection<?> c, Object errorMessage) {
        checkArgument(collectionIsNotEmpty(c), errorMessage);
    }

    /**
     * 断言集合不为空
     */
    public static void checkCollectionIsNotEmpty(Collection<?> c) {
        checkArgument(collectionIsNotEmpty(c));
    }

    /**
     * 断言字符串不为空
     *
     * @param errorMessage 异常信息
     */
    public static void checkStrIsNotBlank(final CharSequence cs, Object errorMessage) {
        checkArgument(strIsNotBlank(cs), errorMessage);
    }

    /**
     * 断言字符串不为空
     */
    public static void checkStrIsNotBlank(final CharSequence cs) {
        checkArgument(strIsNotBlank(cs));
    }

    /**
     * 断言对象不为空
     *
     * @param errorMessage 异常信息
     */
    public static void checkObsIsNotNull(Object cs, Object errorMessage) {
        checkArgument(objectNonNull(cs), errorMessage);
    }

    /**
     * 断言对象不为空
     */
    public static void checkObsIsNotNull(Object cs) {
        checkArgument(objectNonNull(cs));
    }


    /**
     * 统一断言 ,集合不为空,字符串不为空,等等
     */
    public static void checkIsNotEmpty(Object obj) {
        if (isEmpty(obj)) {
            throw new NullPointerException();
        }
    }

    /**
     * 统一断言 ,集合不为空,字符串不为空,等等
     */
    public static void checkIsNotEmpty(Object obj,String message) {
        if (isEmpty(obj)) {
            throw new NullPointerException(message);
        }
    }

}
